package com.baidu.mapapi.demo.ui.gps;

import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.GeoPoint;
import com.baidu.mapapi.ItemizedOverlay;
import com.baidu.mapapi.LocationListener;
import com.baidu.mapapi.MKAddrInfo;
import com.baidu.mapapi.MKBusLineResult;
import com.baidu.mapapi.MKDrivingRouteResult;
import com.baidu.mapapi.MKLocationManager;
import com.baidu.mapapi.MKPoiInfo;
import com.baidu.mapapi.MKPoiResult;
import com.baidu.mapapi.MKSearch;
import com.baidu.mapapi.MKSearchListener;
import com.baidu.mapapi.MKSuggestionResult;
import com.baidu.mapapi.MKTransitRouteResult;
import com.baidu.mapapi.MKWalkingRouteResult;
import com.baidu.mapapi.MapActivity;
import com.baidu.mapapi.MapView;
import com.baidu.mapapi.OverlayItem;
import com.baidu.mapapi.Projection;
import com.baidu.mapapi.demo.BMapHelp;
import com.baidu.mapapi.demo.FrameParam;
import com.baidu.mapapi.demo.R;

/**
 * 
 * @author lilin
 * @date 2012-11-23 下午1:43:34
 * @annotation 根据GPS定位点，先反地址查询，后范围查询，再计算记录
 */
public class BMap_GPS_ReverseAndExtent extends MapActivity {
	public static MapView mapView;

	public static View popView;
	private TextView showTextView;
	private MKSearch mkSearch;

	private LocationListener mLocationListener = null;
	private MKLocationManager locationManager;

	private double gx;
	private double gy;
	private GeoPoint gpsGeoPoint;

	private FrameParam app;

	private Boolean isGPS = true;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 消除状态栏
		requestWindowFeature(Window.FEATURE_NO_TITLE);

		// 强制竖屏
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

		// 键盘默认隐藏
		getWindow().setSoftInputMode(
				WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

		setContentView(R.layout.bmap_markmap);
		// setTitle("定位签到(范围查询)");

		initUI();

		// 初始化搜索
		mkSearch = new MKSearch();
		mkSearch.init(app.mBMapManager, new MySearch());

		mLocationListener = new LocationListener() {

			@Override
			public void onLocationChanged(Location location) {
				if (location != null) {

					if (isGPS == true) {
						dealGPSInfo(location);

					}
				}

			}

		};

		Log.i("andli", "缩放比例(老)=" + mapView.getZoomLevel());
		int num = mapView.getMaxZoomLevel() - mapView.getMaxZoomLevel();
		for (int i = 0; i < num - 1; i++) {
			mapView.getController().zoomIn();
		}
		Log.i("andli", "缩放比例(新)=" + mapView.getZoomLevel());
		Log.i("andli", "最大缩放比例=" + mapView.getMaxZoomLevel());
		Log.i("andli", "最小缩放比例=" + mapView.getMinZoomLevel());
	}

	private void dealGPSInfo(Location location) {
		gx = location.getLatitude();
		gy = location.getLongitude();
		BMapHelp.printXY("GPS坐标", gx, gy);
		gpsGeoPoint = BMapHelp.gpsToGeoPoint(gx, gy);

		// 测试点
		// gpsGeoPoint = new GeoPoint((int) (39.915 * 1E6),
		// (int) (116.404 * 1E6));
		mapView.getController().animateTo(gpsGeoPoint);// 移到已该点为中心

		mkSearch.reverseGeocode(gpsGeoPoint);// 反地址解析

		isGPS = false;

	}

	private void initUI() {
		app = (FrameParam) this.getApplication();
		if (app.mBMapManager == null) {
			app.mBMapManager = new BMapManager(getApplication());
			app.mBMapManager.init(app.mapKey,
					new FrameParam.MyGeneralListener());
		}
		locationManager = app.mBMapManager.getLocationManager();
		app.mBMapManager.start();

		this.initMapActivity(app.mBMapManager);// 初始化

		mapView = (MapView) findViewById(R.id.bmapView);

		mapView.setBuiltInZoomControls(true);// 允许缩放操作
		mapView.getController().setZoom(18);// 设置缩放级别为3-18
		mapView.setDoubleClickZooming(true);// 允许双击放大
		mapView.setDrawOverlayWhenZooming(true);// 设置在缩放动画过程中也显示overlay,默认为不绘制

		// 初始化气泡
		popView = getLayoutInflater().inflate(R.layout.bmap_popview, null);
		mapView.addView(popView, new MapView.LayoutParams(
				MapView.LayoutParams.WRAP_CONTENT,
				MapView.LayoutParams.WRAP_CONTENT, null,
				MapView.LayoutParams.TOP));
		popView.setVisibility(View.GONE);

		showTextView = (TextView) popView.findViewById(R.id.title);
		showTextView.setText("正在搜索中...");
		showTextView.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				showPOIDetail(showTextView.getText().toString().trim());
			}
		});

		// String loginid = DBHelp.getConfigValue(this, ConfigKey.loginid);
		// if (loginid.contains("lil")) {
		// isLongPress = true;
		// }

	}

	/**
	 * @author lilin
	 * @date 2012-11-27 下午4:21:48
	 * @annotation 显示POI详情
	 */
	protected void showPOIDetail(String str) {
		for (int i = 0; i < titleList.size(); i++) {
			if (titleList.get(i).toString().equals(str)) {
				showMKPoiInfoByDialog(BMap_GPS_ReverseAndExtent.this, poiList.get(i));
			}
		}

	}

	// 显示POI详情
	public void showMKPoiInfoByDialog(Context context, final MKPoiInfo poiInfo) {
		BMapHelp.printPoiInfo(this, poiInfo);
		String addresstemp = poiInfo.address;
		if (addresstemp.contains("[地图]")) {
			addresstemp = poiInfo.address.replace("[地图]", "");
		}
		String nametemp = poiInfo.name;
		String texttemp = "";

		StringBuffer sb = new StringBuffer();
		if (!TextUtils.isEmpty(addresstemp) && !addresstemp.equals("null")) {
			sb.append(addresstemp);
		}
		if (!TextUtils.isEmpty(nametemp) && !nametemp.equals("null")) {
			if (nametemp.equals("沙洲职业工学院教学实训基地")) {
				nametemp = "江苏国泰新点软件有限公司";
			}
			sb.append("[" + nametemp + "]");

		}
		texttemp = sb.toString();

		final String address = addresstemp;
		final String name = nametemp;
		final String text = texttemp;

		AlertDialog alertDialog = new AlertDialog.Builder(this)
				.setTitle("地址详情").setMessage(text)
				.setPositiveButton("确定", new AlertDialog.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						// Intent intent = new Intent(BMap_GPS_Extent.this,
						// KaoQingView.class);
						// Bundle bundle = new Bundle();
						//
						// bundle.putString("address", address);
						// bundle.putString("name", name);
						// intent.putExtra("bundle", bundle);
						// setResult(RESULT_OK, intent);
						finish();
					}
				}).setNegativeButton("取消", null).create();
		Window window = alertDialog.getWindow();
		window.setGravity(Gravity.BOTTOM);// 设置显示位置
		WindowManager.LayoutParams lp = window.getAttributes();
		lp.alpha = 0.8f;// 设置透明度:取值范围是从0到1.0。0表 示完全透明,1.0表示不透明
		window.setAttributes(lp);
		alertDialog.show();

	}

	public void showMKAddrInfoByDialog(Context context, final MKAddrInfo poiInfo) {
		BMapHelp.printPoiInfo(this, poiInfo);
		String addresstemp = poiInfo.strAddr;
		if (addresstemp.contains("[地图]")) {
			addresstemp = poiInfo.strAddr.replace("[地图]", "");
		}
		String nametemp = poiInfo.strBusiness;
		String texttemp = "";
		if (!TextUtils.isEmpty(nametemp) && !nametemp.equals("null")) {
			texttemp = addresstemp + "[" + nametemp + "]";
		} else {
			texttemp = addresstemp;
		}

		final String address = addresstemp;
		final String name = nametemp;
		final String text = texttemp;

		AlertDialog alertDialog = new AlertDialog.Builder(this)
				.setTitle("地址详情").setMessage(text)
				.setPositiveButton("确定", new AlertDialog.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						// Intent intent = new Intent(BMap_GPS_Extent.this,
						// KaoQingView.class);
						// Bundle bundle = new Bundle();
						//
						// bundle.putString("address", address);
						// bundle.putString("name", name);
						// intent.putExtra("bundle", bundle);
						// setResult(RESULT_OK, intent);
						finish();
					}
				}).setNegativeButton("取消", null).create();
		Window window = alertDialog.getWindow();
		window.setGravity(Gravity.BOTTOM);// 设置显示位置
		WindowManager.LayoutParams lp = window.getAttributes();
		lp.alpha = 0.8f;// 设置透明度:取值范围是从0到1.0。0表 示完全透明,1.0表示不透明
		window.setAttributes(lp);
		alertDialog.show();

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, 0, 0, "中心点坐标");
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch (item.getItemId()) {
		case 0:
			addMarkOverlay(this, mapView.getMapCenter(),
					R.drawable.bmap_point_green);
			break;

		default:
			break;
		}
		return super.onMenuItemSelected(featureId, item);
	}

	public void addMarkOverlay(Context con, GeoPoint geoPoint, int id) {

		// mapView.getController().animateTo(geoPoint);// 移到已该点为中心
		mapView.getOverlays().clear();// 添加前清空所有图层
		BMap_MarkOverlay markOverlay = new BMap_MarkOverlay(con, geoPoint,
				BMapHelp.setMarkImg(this, id));
		mapView.getOverlays().add(markOverlay); // 添加ItemizedOverlay实例到mMapView
		mapView.invalidate();

	}

	public void addMarkOverlay(Context con, List<GeoPoint> plist, int id,
			List<String> title) {
		// BMapHelp.printPoint("第一个POI点", plist.get(0));
		// mapView.getController().animateTo(plist.get(0));// 移到已该点为中心
		mapView.getOverlays().clear();// 添加前清空所有图层
		BMap_MarkOverlay markOverlay = new BMap_MarkOverlay(con, plist,
				BMapHelp.setMarkImg(con, id), title);
		mapView.getOverlays().add(markOverlay); // 添加ItemizedOverlay实例到mMapView
		mapView.invalidate();

		// 计算每个POI点和定位点直接的距离
		if (plist.size() > 0) {
			for (int i = 0; i < plist.size(); i++) {
				String distance = BMapHelp.calculate2Distance(plist.get(i),
						gpsGeoPoint);
				Log.i("andli", "与" + poiList.get(i).name + "相距" + distance);
			}
		}

	}

	@Override
	protected void onPause() {
		FrameParam app = (FrameParam) this.getApplication();
		if (app.mBMapManager != null) {
			locationManager.removeUpdates(mLocationListener);
			app.mBMapManager.stop();
		}
		super.onPause();
	}

	@Override
	protected void onResume() {
		FrameParam app = (FrameParam) this.getApplication();

		locationManager.requestLocationUpdates(mLocationListener);

		app.mBMapManager.start();
		super.onResume();
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	@Override
	protected void onDestroy() {

		FrameParam app = (FrameParam) this.getApplication();
		if (app.mBMapManager != null) {
			app.mBMapManager.destroy();
			app.mBMapManager = null;
		}
		super.onDestroy();
	}

	// 标记图层
	class BMap_MarkOverlay extends ItemizedOverlay<OverlayItem> implements
			OnGestureListener {

		public List<OverlayItem> itemList = new ArrayList<OverlayItem>();

		private Drawable img;
		public Context con;

		private GestureDetector gestureScanner = new GestureDetector(this);

		BMap_MarkOverlay(Context context, GeoPoint mGeoPoint, Drawable marker) {
			super(boundCenterBottom(marker));
			itemList = new ArrayList<OverlayItem>();
			this.img = marker;
			this.con = context;

			itemList.add(new OverlayItem(mGeoPoint, "", ""));

			populate(); // 刷新地图
		}

		BMap_MarkOverlay(Context context, List<GeoPoint> pList,
				Drawable marker, List<String> title) {
			super(boundCenterBottom(marker));
			itemList = new ArrayList<OverlayItem>();
			this.img = marker;
			this.con = context;

			for (int i = 0; i < pList.size(); i++) {
				itemList.add(new OverlayItem(pList.get(i), "", title.get(i)));
			}

			populate(); // 刷新地图
		}

		public void updateOverlay() {
			populate();
		}

		@Override
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {

			Projection projection = mapView.getProjection();// Projection接口用于屏幕像素坐标和经纬度坐标之间的变换

			for (int index = size() - 1; index >= 0; index--) { // 遍历mGeoList
				OverlayItem overLayItem = getItem(index); // 得到给定索引的item

				String title = overLayItem.getTitle();

				Point point = projection.toPixels(overLayItem.getPoint(), null);// 把经纬度变换到相对于MapView左上角的屏幕像素坐标

				// 可在此处添加您的绘制代码
				Paint mPaint = new Paint();
				mPaint.setColor(Color.BLUE);
				mPaint.setTextSize(15);
				canvas.drawText(title, point.x - 50, point.y, mPaint); // 绘制文本
			}

			super.draw(canvas, mapView, shadow);
			boundCenterBottom(img);// 调整一个drawable边界，使得（0，0）是这个drawable底部最后一行中心的一个像素
		}

		@Override
		protected OverlayItem createItem(int i) {
			return itemList.get(i);
		}

		@Override
		public int size() {
			return itemList.size();
		}

		@Override
		protected boolean onTap(int i) {// 处理当点击事件
			setFocus(itemList.get(i));// 获得焦点
			GeoPoint geoPoint = itemList.get(i).getPoint(); // 更新气泡位置,并使之显示
			LayoutParams params = new MapView.LayoutParams(
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
					geoPoint, MapView.LayoutParams.BOTTOM_CENTER);
			mapView.updateViewLayout(popView, params);
			mapView.updateViewLayout(popView, params);
			// popView.setVisibility(View.VISIBLE);
			// showTextView.setText(itemList.get(i).getSnippet());
			showPOIDetail(itemList.get(i).getSnippet());
			return true;
		}

		@Override
		public boolean onTap(GeoPoint arg0, MapView arg1) {
			popView.setVisibility(View.GONE);// 消去弹出的气泡
			return super.onTap(arg0, arg1);
		}

		@Override
		public boolean onDown(MotionEvent arg0) {
			return false;
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {

			return false;
		}

		@Override
		public void onLongPress(MotionEvent e) {
			longPressEvent(e);
		}

		@Override
		public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
				float arg3) {
			return false;
		}

		@Override
		public void onShowPress(MotionEvent arg0) {

		}

		@Override
		public boolean onSingleTapUp(MotionEvent arg0) {
			return false;
		}

		// ***必不可少，否则触摸事件无效
		@Override
		public boolean onTouchEvent(MotionEvent arg0, MapView arg1) {
			return gestureScanner.onTouchEvent(arg0);
		}

	}

	/**
	 * 
	 * @author lilin
	 * @date 2012-11-22 下午4:46:03
	 * @annotation 搜索类（内部类）
	 */
	class MySearch implements MKSearchListener {
		// 反地址查询结果
		@Override
		public void onGetAddrResult(MKAddrInfo arg0, int arg1) {

			if (arg1 == 100) {
				showTextView.setText("地址正确，暂无法查询");
				return;
			}
			if (arg0 == null) {
				showTextView.setText("查不到此地信息");
				return;
			}

			if (arg0 != null) {
				getAddrResult(arg0);
			}

		}

		@Override
		public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {

		}

		@Override
		public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) {

		}

		// 按范围查询结果
		@Override
		public void onGetPoiResult(MKPoiResult res, int type, int error) {

			if (error != 0 || res == null) { // 错误号可参考MKEvent中的定义
				// 在地图上显示POI标志点
				addMarkOverlay(BMap_GPS_ReverseAndExtent.this, pList,
						R.drawable.bmap_point_green, titleList);

				// ToastHelp.showToast(BMap_GPS_Extent.this, pList.size() +
				// "个");
				return;
			}
			getPOIResult(res);

		}

		@Override
		public void onGetRGCShareUrlResult(String arg0, int arg1) {

		}

		@Override
		public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) {

		}

		@Override
		public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) {

		}

		@Override
		public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) {

		}

	}

	private String cityName = "";
	private int searchType = 0;// 0,范围搜索；1，反地址搜索
	private int searchExtent = 500;// 搜索范围
	List<GeoPoint> pList = new ArrayList<GeoPoint>();
	List<String> titleList = new ArrayList<String>();
	List<MKPoiInfo> poiList = new ArrayList<MKPoiInfo>();// 查询到的点的列表

	/**
	 * @author lilin
	 * @date 2012-11-26 上午9:26:37
	 * @annotation 获得反地址查询的结果
	 */
	public void getAddrResult(MKAddrInfo arg0) {
		try {
			if (arg0 != null) {
				// 清空
				pList.clear();
				titleList.clear();
				poiList.clear();

				// 处理反地址查询到的点信息
				String pAddress = arg0.strAddr;
				String pName = arg0.strBusiness;
				GeoPoint geoPoint = arg0.geoPt;
				pList.add(geoPoint);
				titleList.add(pAddress);

				MKPoiInfo gpsPOIInfo = new MKPoiInfo();
				gpsPOIInfo.address = pAddress;
				gpsPOIInfo.name = pName;
				gpsPOIInfo.pt = geoPoint;

				poiList.add(gpsPOIInfo);

				// 处理周围POI
				if (arg0.type == MKAddrInfo.MK_REVERSEGEOCODE) {
					if (arg0.poiList != null && arg0.poiList.size() > 0) {
						List<MKPoiInfo> nearbyPoiList = arg0.poiList;
						for (int i = 0; i < nearbyPoiList.size(); i++) {
							pList.add(nearbyPoiList.get(i).pt);
							titleList.add(nearbyPoiList.get(i).name);
							poiList.add(nearbyPoiList.get(i));
						}
					}
				}

				// BMapHelp.printMKGeocoderAddressComponent(arg0.addressComponents);
				if (searchType == 0) {
					//范围查询
					String district = arg0.addressComponents.district;
					if (!TextUtils.isEmpty(district) && district != "null") {
						cityName = district;
					} else {
						cityName = arg0.addressComponents.city;
					}
					Log.i("andli", "范围查询关键字" + cityName);
					if (!TextUtils.isEmpty(cityName)) {
						mkSearch.poiSearchNearBy(cityName, gpsGeoPoint,
								searchExtent);// 范围搜索
					} else {
						// 在地图上显示POI标志点
						addMarkOverlay(BMap_GPS_ReverseAndExtent.this, pList,
								R.drawable.bmap_point_green, titleList);
					}
				}

				// 长按标记
				// if (isLongPress) {
				// if (locType.equals(LONGPRESS)) {
				// BMapHelp.showMKAddrInfo(arg0);
				//
				// showMKAddrInfoByDialog(this, arg0);
				//
				// if (arg0.type == MKAddrInfo.MK_REVERSEGEOCODE) {
				// if (arg0.poiList != null && arg0.poiList.size() > 0) {
				// poiList.clear();
				// poiList = arg0.poiList;
				// List<GeoPoint> pList = new ArrayList<GeoPoint>();
				// List<String> titleList = new ArrayList<String>();
				// for (int i = 0; i < poiList.size(); i++) {
				// pList.add(poiList.get(i).pt);
				// titleList.add(poiList.get(i).name);
				// }
				// // 在地图上显示POI标志点
				// addMarkOverlay(BMap_GPS_Extent.this, pList,
				// R.drawable.bmap_point_green, titleList);
				// }
				// }
				// }
				//
				// }
			}
		} catch (Exception e) {
			e.printStackTrace();
			// LogHelp.Log2SDErr(e);
		}

	}

	/**
	 * @author lilin
	 * @date 2012-11-26 上午9:26:37
	 * @annotation 获取范围查询的结果
	 */
	public void getPOIResult(MKPoiResult poiResult) {
		if (!locType.equals(LONGPRESS)) {
			int curNum = poiResult.getCurrentNumPois();// 只显示10个结果
			if (curNum > 0) {
				for (int i = 0; i < curNum; i++) {
					poiResult.getPoi(i).city = cityName;// 按范围查询到的city为空，所以这边我赋给它一个值
					pList.add(poiResult.getPoi(i).pt);
					titleList.add(poiResult.getPoi(i).name);
					poiList.add(poiResult.getPoi(i));
				}
				// 在地图上显示POI标志点
				addMarkOverlay(BMap_GPS_ReverseAndExtent.this, pList,
						R.drawable.bmap_point_green, titleList);

			}
			// ToastHelp.showToast(this, pList.size() + "个");

		}
	}

	private boolean isLongPress = false;
	private String locType = "";// 定位方式:长按定位，GPS定位
	private final static String LONGPRESS = "LONGPRESS";

	/**
	 * @author lilin
	 * @date 2012-11-22 下午4:48:51
	 * @annotation 长按事件
	 */
	public void longPressEvent(MotionEvent e) {
		if (isLongPress) {
			locType = LONGPRESS;
			float x = e.getX();
			float y = e.getY();

			GeoPoint point = mapView.getProjection().fromPixels((int) x,
					(int) y);// 像素点转换成坐标点
			mapView.getController().animateTo(point);
			addMarkOverlay(this, point, R.drawable.bmap_point_red);// 添加标注

			// 根据地理坐标点获取地址信息 异步函数，返回结果在MKSearchListener里的onGetAddrResult方法通知
			mkSearch.reverseGeocode(point);

			mapView.invalidate();// 刷新

			MapView.LayoutParams layoutParams = (MapView.LayoutParams) popView
					.getLayoutParams();
			layoutParams.point = point;// 设置显示的位置
			mapView.updateViewLayout(popView, layoutParams);
		}

	}
}
